package br.com.iswe.gwt.crud.client;

import java.util.ArrayList;
import java.util.List;

import br.com.iswe.core.entidades.gwt.BeanMap;
import br.com.iswe.core.entidades.gwt.RemoteEntityObject;
import br.com.iswe.gwt.ui.client.CheckBoxBag;
import br.com.iswe.gwt.ui.client.ListPanelListener;
import br.com.iswe.gwt.ui.client.ListenerCollection;
import br.com.iswe.gwt.ui.client.QueryInfo;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;

import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.Hyperlink;

@SuppressWarnings("unchecked")
public abstract class ListPanelAbstract<E extends RemoteEntityObject> extends Composite {

	public ListPanelAbstract(){}
	
	protected static final String ORDER_LINK_TOKEN = "ORDER_LINK";
	
	private boolean pagination = false;
	
	public void setupScreen(){
		getFlexTable().setStyleName("iswe-listPanel");
		getFlexTable().getRowFormatter().setStyleName(0, "iswe-listHeadRow");
	}
	
	protected ListPanelListener<E> listPanelListener = null;
	public void setListPanelListener(ListPanelListener<E> listPanelListener) {
		this.listPanelListener = listPanelListener;
	}
	
	public ListenerCollection<E> onSelectListener = new ListenerCollection<E>();
	
	public ListenerCollection<ListPanelAbstract<E>> onCheckBoxValueChanged = new ListenerCollection<ListPanelAbstract<E>>();
	
	protected List<CheckBoxBag> checkBoxList = new ArrayList<CheckBoxBag>();
	
	protected abstract FlexTable getFlexTable();
	
	public void search(){
		if(listPanelListener == null){
			return;
		}
		//Query Info
		QueryInfo queryInfo = listPanelListener.getQueryInfo();
		//check for pagination
		if(hasPagination()){
			queryInfo.setPaginacao(true);
			queryInfo.setTamanhoPagina(getPageSize());
			queryInfo.setNumeroPagina(1);
		}
			
		searchImpl(queryInfo);
	}
	
	protected int getPageSize() {
		return 10;
	}

	protected abstract void searchImpl(final QueryInfo queryInfo);

	protected Anchor createColumnHeader(String title, String propertyToOrderBy) {
		Anchor headerLink = new Anchor(title);
		headerLink.addClickHandler(buildOrderClickListener(propertyToOrderBy));
		return headerLink;
	}
	
	public ClickHandler buildOrderClickListener(final String property){
		ClickHandler handler = new ClickHandler(){
			private int state = 0;
			public void onClick(ClickEvent event) {
				orderBy(state, property );
				if(state == 0){
					state = 1;
				}
				else{
					state = 0;
				}
			}
		};
		return handler;
	}
	
	public void orderBy(int state, String property) {
		if(listPanelListener == null){
			return;
		}
		//Query Info
		QueryInfo queryInfo = listPanelListener.getQueryInfo();
		queryInfo.getOrderList().clear();
		if(state == 0){
			queryInfo.addOrderPropertyAsc(property);
		}
		else{
			queryInfo.addOrderPropertyDesc(property);
		}
		
		searchImpl(queryInfo);
	}
	
	public void gotoPage(int pageNumber, int pageSize){
		if(listPanelListener == null){
			return;
		}
		QueryInfo queryInfo = listPanelListener.getQueryInfo();
		queryInfo.setPaginacao(true);
		queryInfo.setNumeroPagina(pageNumber);
		queryInfo.setTamanhoPagina(pageSize);

		searchImpl(queryInfo);
	}
	
	protected void notifyCheckBoxValueChanged() {
		onCheckBoxValueChanged.execute(this);
	}
	
	protected PaginationPanel paginationPanelInstance = null;
	protected PaginationPanel getPaginationPanel() {
		if(paginationPanelInstance == null){
			paginationPanelInstance = new PaginationPanel(this);
			//default values
			paginationPanelInstance.setPageSize(getPageSize());
			paginationPanelInstance.setPageNumber(1);
		}
		return paginationPanelInstance;
	}

	public List<BeanMap> getSelectedItensAsBeanMap() {
		List<BeanMap> selectedItens = new ArrayList<BeanMap>();
		for (int i = 0; i < checkBoxList.size(); i++) {
			CheckBoxBag bag = checkBoxList.get(i);
			if(bag.getValue()){
				selectedItens.add((BeanMap)bag.getEntityObject());
			}
		}
		return selectedItens;
	}
	
	public List<E> getSelectedItens() {
		List selectedItens = new ArrayList();
		for (int i = 0; i < checkBoxList.size(); i++) {
			CheckBoxBag bag = checkBoxList.get(i);
			if(bag.getValue()){
				selectedItens.add(bag.getEntityObject());
			}
		}
		return selectedItens;
	}

	//internall HyperLink implementation to be used as select all and select none on top of the checkboxes column
	class CustomHyperLink extends Hyperlink{
		private int state = 0; //0 - All ; 1 - None
		
		private String allText = "All";
		private String noneText = "None";
		
		public CustomHyperLink(){
			super("All", "SELECT_ALL_NONE");
			addClickHandler(new ClickHandler(){
				public void onClick(ClickEvent event) {
					//
					CustomHyperLink customLink = (CustomHyperLink)event.getSource();
					if(customLink.state == 0){
						//select all checkboxes
						customLink.setState(true);
					}
					else{
						//diselect all checkboxes
						customLink.setState(false);
					}
					
				}});
		}
		
		public void setState(boolean selectAll){
			if(selectAll){
				//select all checkboxes
				setAllCheckBoxesImpl(true);
				this.setText(noneText);
				this.state = 1;
			}
			else{
				//diselect all checkboxes
				setAllCheckBoxesImpl(false);
				this.setText(allText);
				this.state = 0;
			}
			
		}
	}
	
	protected CustomHyperLink selectAllNoneLink = new CustomHyperLink();
	
	public void setAllCheckBoxes(boolean checked){
		selectAllNoneLink.setState(checked);
	}
	
	private void setAllCheckBoxesImpl(boolean checked){
		for (int i = 0; i < checkBoxList.size(); i++) {
			CheckBox checkBox = (CheckBox)checkBoxList.get(i);
			checkBox.setValue(checked);
		}
		notifyCheckBoxValueChanged();
	}
	
	protected boolean checkBoxesEnabled = false;
	public boolean isCheckBoxesEnabled() {
		return checkBoxesEnabled;
	}
	public void setCheckBoxesEnabled(boolean checkBoxesEnabled) {
		this.checkBoxesEnabled = checkBoxesEnabled;
		if(checkBoxesEnabled){
			getFlexTable().setWidget(0, 0, selectAllNoneLink);
			getFlexTable().getCellFormatter().setHorizontalAlignment(0, 0, HasHorizontalAlignment.ALIGN_CENTER);
		}
		selectAllNoneLink.setVisible(checkBoxesEnabled);
	}

	protected boolean linkEnabled = false;
	public boolean isLinkEnabled() {
		return linkEnabled;
	}
	public void setLinkEnabled(boolean linkEnabled) {
		this.linkEnabled = linkEnabled;
	}

	public boolean hasPagination() {
		return pagination;
	}
	public void setPagination(boolean pagination) {
		this.pagination = pagination;
	}
}
